﻿package framework.core;

import java.util.* ;



public class Conditions 
{
	public static final int EQUAL = 0;
	public static final int GREATER_EQUAL = 1 ;
	public static final int GREATER_THAN = 2 ;
	public static final int LESS_EQUAL = 3 ;
	public static final int LESS_THAN = 4 ;
	public static final int NOT_EQUAL = 5 ;
	public static final int LIKE = 6 ;
	
	public static final int IN = 7;
	public static final int BETWEEN = 8;
	public static final int CUSTOM = 9 ;
	
	public static final int TYPE_MIN = 0 ;
	public static final int TYPE_MAX = 9 ;
	
	private Vector m_conditions = new Vector();
	private Values m_params     = new Values();

	//interface to final user
	public void add(Condition c) throws Exception
	{
		//if(c==null) Logger.throwException(this,"无法增加空的查询条件!");
		if(c==null) return ;
		
		m_conditions.add(c);
		for(int i=0;i<c.getParamCount();i++)
		{
			m_params.add(c.getParam(i));
		}
	}
	
	public static String getConditionSql(String field_name,int type,int paramCount) throws Exception 
	{
		if(type<TYPE_MIN||type>TYPE_MAX)
		{
			Logger.throwException("Conditions.getConditionSql()","未知的查询条件类型,type="+type);
		}
		
		if(type==CUSTOM)
		{
			return field_name ;
		}
		else if(type==IN)
		{
			if(paramCount<1) Logger.throwException("Conditions.getConditionSql()","in语法没有参数值.");
			
			String sql = field_name + " in (";
			for(int i=0;i<paramCount;i++)
			{
				if(i==0)
				{
					sql += "?";
				}
				else
				{
					sql += ",?" ;
				}
			}
			sql += ")";
			return sql ;
		}
		else if(type==BETWEEN)
		{
			if(paramCount!=2) Logger.throwException("Conditions.getConditionSql()","between语法参数值不是2个.");	
					
			String sql = field_name + " between ? and ? ";
			return sql ;
		}
		else
		{
			if(paramCount!=1) Logger.throwException("Conditions.getConditionSql()","单值查询语法参数值不是1个.");	
			
			String sql = "";
			if(type==EQUAL)
			{
				sql = field_name + "=?";
			}
			else if(type==GREATER_EQUAL)
			{
				sql = field_name + ">=?";
			}
			else if(type==GREATER_THAN)
			{
				sql = field_name + ">?";
			}
			else if(type==LESS_EQUAL)
			{
				sql = field_name + "<=?";
			}
			else if(type==LESS_THAN)
			{
				sql = field_name + "<?";
			}
			else if(type==NOT_EQUAL)
			{
				sql = field_name + "<>?";
			}
			else if(type==LIKE)
			{
				sql = field_name + " like ?";
			}
			return sql ;
		}
	}
	
	//none value
	public void add(String sql) throws Exception
	{
		add(new Condition(sql));
	}
		
	//Values
	public void add(String field_name,int type,Values values) throws Exception 
	{
		int paramCount ;
		if(values==null)
		{
			paramCount = 0 ;
		}
		else
		{
			paramCount = values.size();
		}
		String sql = getConditionSql(field_name,type,paramCount);
		add(new Condition(sql,values));
	}
	
	//int[]
	public void add(String field_name,int type,int[] values) throws Exception 
	{
		int paramCount ;
		if(values==null)
		{
			paramCount = 0 ;
		}
		else
		{
			paramCount = values.length;
		}
		String sql = getConditionSql(field_name,type,paramCount);
		add(new Condition(sql,values));
	}
	
	//double[]
	public void add(String field_name,int type,double[] values) throws Exception 
	{
		int paramCount ;
		if(values==null)
		{
			paramCount = 0 ;
		}
		else
		{
			paramCount = values.length;
		}
		String sql = getConditionSql(field_name,type,paramCount);
		add(new Condition(sql,values));
	}
	
	//String[]
	public void add(String field_name,int type,String[] values) throws Exception 
	{
		int paramCount ;
		if(values==null)
		{
			paramCount = 0 ;
		}
		else
		{
			paramCount = values.length;
		}
		String sql = getConditionSql(field_name,type,paramCount);
		add(new Condition(sql,values));
	}
	
	//int
	public void add(String field_name,int type,int v) throws Exception
	{
		String sql = getConditionSql(field_name,type,1);
		add(new Condition(sql,v));
	}
	
	//double
	public void add(String field_name,int type,double v) throws Exception
	{
		String sql = getConditionSql(field_name,type,1);
		add(new Condition(sql,v));
	}
	
	//String
	public void add(String field_name,int type,String v) throws Exception
	{
		String sql = getConditionSql(field_name,type,1);
		add(new Condition(sql,v));
	}

	//Value
	public void add(String field_name,int type,Value v) throws Exception
	{
		String sql = getConditionSql(field_name,type,1);
		add(new Condition(sql,v));
	}
    
    //------------------------------------------------------
    /**
     * 
     * 加入xml db查询条件
     */
    public void addXMLCondition(String field_name, String xPath,
            int type, Value v) throws Exception
    {
        String xmlFieldName = "extract("+ field_name +", '"+ xPath +"/text()').getStringVal()";
        String sql = getConditionSql(xmlFieldName, type, 1);
        add(new Condition(sql, v));
    }
    
    public void addXMLCondition(String field_name, String xPath, Value v) throws Exception
    {
        addXMLCondition(field_name, xPath, EQUAL, v);
    }
    public void addXMLCondition(String field_name, String xPath, int v) throws Exception
    {
        String xmlFieldName = "extract("+ field_name +", '"+ xPath +"/text()').getStringVal()";
        String sql = getConditionSql(xmlFieldName, EQUAL, 1);
        add(new Condition(sql, v));
    }
    public void addXMLCondition(String field_name, String xPath, double v) throws Exception
    {
        String xmlFieldName = "extract("+ field_name +", '"+ xPath +"/text()').getStringVal()";
        String sql = getConditionSql(xmlFieldName, EQUAL, 1);
        add(new Condition(sql, v));
    }
    public void addXMLCondition(String field_name, String xPath, String v) throws Exception
    {
        String xmlFieldName = "extract("+ field_name +", '"+ xPath +"/text()').getStringVal()";
        String sql = getConditionSql(xmlFieldName, EQUAL, 1);
        add(new Condition(sql, v));
    }    
    
	//------------------------------------------------------
	
	//EQUAL int
	public void add(String field_name,int v) throws Exception
	{
		String sql = getConditionSql(field_name,EQUAL,1);
		add(new Condition(sql,v));
	}
	
	//EQUAL double
	public void add(String field_name,double v) throws Exception
	{
		String sql = getConditionSql(field_name,EQUAL,1);
		add(new Condition(sql,v));
	}
	
	//EQUAL String
	public void add(String field_name,String v) throws Exception
	{
		String sql = getConditionSql(field_name,EQUAL,1);
		add(new Condition(sql,v));
	}
	//EQUAL Value
	public void add(String field_name,Value v) throws Exception
	{
		String sql = getConditionSql(field_name,EQUAL,1);
		add(new Condition(sql,v));
	}

	//BETWEEN 
	public void addBetween(String field_name,int v1,int v2) throws Exception
	{
		String sql = getConditionSql(field_name,BETWEEN,2);
		Values values = new Values();
		values.add(new Value(v1));
		values.add(new Value(v2));
		add(new Condition(sql,values));
	}
	public void addBetween(String field_name,double v1,double v2) throws Exception
	{
		String sql = getConditionSql(field_name,BETWEEN,2);
		Values values = new Values();
		values.add(new Value(v1));
		values.add(new Value(v2));
		add(new Condition(sql,values));
	}
	public void addBetween(String field_name,String v1,String v2) throws Exception
	{
		String sql = getConditionSql(field_name,BETWEEN,2);
		Values values = new Values();
		values.add(new Value(v1));
		values.add(new Value(v2));
		add(new Condition(sql,values));
	}
	


	//interface to DBEngine
	public String getSql()
	{
		String sql = "";
		
		for(int i=0;i<m_conditions.size();i++)
		{
			Condition condition = (Condition)m_conditions.get(i);
			if(i==0)
			{
				sql += " where " + condition.getSql();
			}
			else
			{
				sql += " and " + condition.getSql();
			}
		}
		return sql;
	}
	
	public int getParamCount()
	{
		return m_params.size() ;
	}
	public Value getParam(int index)
	{
		return m_params.get(index);
	}
	
	//clear all! then wo can reuse it.
	public void clear()
	{
		m_conditions.clear();
		m_params.clear();	
	}
	
	public String viewSql(String sSql)
	{
		String sql = "sql="+sSql ;
		sql += getSql();
		try {
			for(int i=0;i<getParamCount();i++)
			{
				Value value = (Value)getParam(i);
				if(value.getType() == Value.TYPE_STRING)
					sql = StringUtil.replaceFirst(sql, "?", "'"+value.getString() + "'");
				else if(value.getType() == Value.TYPE_INT)
					sql = StringUtil.replaceFirst(sql, "?", String.valueOf(value.getInt()));
				else if(value.getType() == Value.TYPE_DOUBLE)
					sql = StringUtil.replaceFirst(sql, "?", String.valueOf(value.getDouble()));
				else ;	
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return sql;
	}	
	
//	public String getExcuteableSql(String sSql)
//	{
//		String sql = "sql="+sSql ;
//		sql += getSql();
//		try {
//			for(int i=0;i<getParamCount();i++)
//			{
//				Value value = (Value)getParam(i);
//				if(value.getType() == Value.TYPE_STRING)
//					sql = StringUtil.replaceFirst(sql, "?", "'"+ StringUtil.replace(value.getString(), "'", "") + "'");
//				else if(value.getType() == Value.TYPE_INT)
//					sql = StringUtil.replaceFirst(sql, "?", String.valueOf(value.getInt()));
//				else if(value.getType() == Value.TYPE_DOUBLE)
//					sql = StringUtil.replaceFirst(sql, "?", String.valueOf(value.getDouble()));
//				else ;	
//			}
//		} catch (Exception e) {
//			e.printStackTrace();
//		}
//		return sql;		
//	}
	
}
